package com.haohan.cloud.scm.saleb.core.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.haohan.cloud.scm.api.bill.dto.OrderInfoDTO;
import com.haohan.cloud.scm.api.bill.entity.ReceivableBill;
import com.haohan.cloud.scm.api.constant.NumberPrefixConstant;
import com.haohan.cloud.scm.api.constant.enums.bill.OrderTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.crm.PayStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.saleb.BillTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.saleb.BuyOrderStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.saleb.DetailSummaryFlagEnum;
import com.haohan.cloud.scm.api.goods.dto.GoodsModelDTO;
import com.haohan.cloud.scm.api.goods.vo.GoodsModelVO;
import com.haohan.cloud.scm.api.manage.entity.Merchant;
import com.haohan.cloud.scm.api.opc.entity.ShipRecord;
import com.haohan.cloud.scm.api.saleb.dto.BuyOrderSqlDTO;
import com.haohan.cloud.scm.api.saleb.entity.BuyOrder;
import com.haohan.cloud.scm.api.saleb.entity.BuyOrderDetail;
import com.haohan.cloud.scm.api.saleb.entity.Buyer;
import com.haohan.cloud.scm.api.saleb.req.BuyDetailModifyReq;
import com.haohan.cloud.scm.api.saleb.req.BuyOrderModifyReq;
import com.haohan.cloud.scm.api.saleb.req.CreateBillBathReq;
import com.haohan.cloud.scm.api.saleb.req.QueryBuyOrderReq;
import com.haohan.cloud.scm.api.saleb.req.order.BuyOrderEditReq;
import com.haohan.cloud.scm.api.saleb.trans.SalebTrans;
import com.haohan.cloud.scm.api.saleb.vo.BuyOrderDetailVO;
import com.haohan.cloud.scm.api.saleb.vo.BuyOrderVO;
import com.haohan.cloud.scm.common.tools.exception.EmptyDataException;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.common.tools.thread.ScmGlobalThreadPool;
import com.haohan.cloud.scm.common.tools.util.ScmIncrementUtil;
import com.haohan.cloud.scm.saleb.core.BuyOrderCoreService;
import com.haohan.cloud.scm.saleb.service.BuyOrderDetailService;
import com.haohan.cloud.scm.saleb.service.BuyOrderService;
import com.haohan.cloud.scm.saleb.service.BuyerService;
import com.haohan.cloud.scm.saleb.utils.ScmSaleBUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author dy
 * @date 2019/10/9
 */
@Service
@AllArgsConstructor
public class BuyOrderCoreServiceImpl implements BuyOrderCoreService {

    private final BuyerService buyerService;
    private final BuyOrderService buyOrderService;
    private final BuyOrderDetailService buyOrderDetailService;
    private final ScmSaleBUtils scmSaleBUtils;
    private final ScmIncrementUtil scmIncrementUtil;

    /**
     * 新增采购单
     *
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BuyOrderVO addBuyOrder(BuyOrderEditReq req) {
        Buyer buyer = checkBuyer(req.getBuyerId());
        BuyOrder order = req.transToAdd(buyer);
        // 明细处理
        int size = Math.max(8, req.getDetailList().size() * 4 / 3 + 1);
        // 保留的明细
        Map<String, BuyOrderDetail> detailMap = new HashMap<>(size);
        Map<String, GoodsModelVO> modelMap = new HashMap<>(size);
        modifyOrderDetail(req.getDetailList(), new HashMap<>(8), modelMap, detailMap, buyer.getId(), LocalDate.now());

        List<BuyOrderDetail> detailList = new ArrayList<>(detailMap.values());
        if (CollUtil.isEmpty(detailList)) {
            throw new ErrorDataException("商品明细无效");
        }
        order.setGoodsNum(modelMap.size());
        return saveOrderWithDetail(order, detailList, buyer);
    }

    /**
     * 采购订单保存(新增或修改)
     *
     * @param order      id==null区分:新增或 修改(buyId必须)
     * @param detailList
     * @param buyer
     * @return
     */
    private BuyOrderVO saveOrderWithDetail(BuyOrder order, List<BuyOrderDetail> detailList, Buyer buyer) {
        boolean addFlag = null == order.getId();
        String buyOrderSn = addFlag ? scmIncrementUtil.inrcSnByClass(BuyOrder.class, NumberPrefixConstant.BUY_ORDER_SN_PRE) : order.getBuyId();
        order.setBuyId(buyOrderSn);
        // 合计金额
        BigDecimal sum = BigDecimal.ZERO;
        for (BuyOrderDetail detail : detailList) {
            sum = sum.add(detail.getGoodsNum().multiply(detail.getBuyPrice()));
            detail.setBuyId(buyOrderSn);
            detail.setBuyerId(buyer.getId());
            detail.setPmId(buyer.getPmId());
            if (null == detail.getId()) {
                buyOrderDetailService.save(detail);
            } else {
                buyOrderDetailService.updateById(detail);
            }
            // todo 推送云打印
        }
        BigDecimal otherAmount = order.getShipFee();
        if (null == otherAmount) {
            otherAmount = BigDecimal.ZERO;
            order.setShipFee(otherAmount);
        }
        sum = sum.add(otherAmount);
        order.setGenPrice(sum);
        order.setTotalPrice(sum);
        // 默认状态
        order.setStatus(BuyOrderStatusEnum.submit);
        order.setPayStatus(PayStatusEnum.wait);
        if (addFlag) {
            buyOrderService.save(order);
        } else {
            buyOrderService.updateById(order);
        }
        // 业务动态
        scmSaleBUtils.createCustomerBuyDynamic(SalebTrans.transToDynamic(order, buyer, addFlag));
        return new BuyOrderVO(order);
    }

    /**
     * 修改采购单
     * 状态限制: 已下单
     *
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean modifyBuyOrder(BuyOrderEditReq req) {
        // 订单修改
        BuyOrder oldOrder = checkBuyOrder(req.getBuyOrderSn());
        checkModifyStatus(oldOrder);
        List<BuyOrderDetail> existList = buyOrderDetailService.findListBySn(req.getBuyOrderSn());
        if (CollUtil.isEmpty(existList)) {
            throw new EmptyDataException("订单明细有误");
        }
        Buyer buyer = checkBuyer(req.getBuyerId());
        BuyOrder update = req.transToModify(buyer);
        update.setId(oldOrder.getId());
        // 明细处理
        // 已存在明细
        int size = Math.max(8, existList.size() * 4 / 3 + 1);
        Map<String, BuyOrderDetail> existMap = existList.stream().collect(Collectors.toMap(BuyOrderDetail::getGoodsModelId, Function.identity(), (oldValue, value) -> value));
        size = Math.max(size, req.getDetailList().size() * 4 / 3 + 1);
        // 保留的明细
        Map<String, BuyOrderDetail> detailMap = new HashMap<>(size);
        Map<String, GoodsModelVO> modelMap = new HashMap<>(size);
        // 定价日期为下单当天
        modifyOrderDetail(req.getDetailList(), existMap, modelMap, detailMap, buyer.getId(), oldOrder.getBuyTime().toLocalDate());
        List<BuyOrderDetail> detailList = new ArrayList<>(detailMap.values());
        if (CollUtil.isEmpty(detailList)) {
            // 无保存明细则取消订单
            return cancelBuyOrder(update);
        }
        update.setGoodsNum(modelMap.size());
        // 删除多余
        existMap.values().forEach(detail -> buyOrderDetailService.removeById(detail.getId()));
        saveOrderWithDetail(update, detailList, buyer);
        // 已创建账单、发货单更新
        scmSaleBUtils.updateShipRecord(update.getBuyId(), OrderTypeEnum.buy);
        scmSaleBUtils.updateBillByOrder(update.getBuyId(), BillTypeEnum.order);
        return true;
    }

    private void modifyOrderDetail(List<BuyDetailModifyReq> detailList, Map<String, BuyOrderDetail> existMap, Map<String, GoodsModelVO> modelMap, Map<String, BuyOrderDetail> detailMap, String buyerId, LocalDate pricingDate) {
        detailList.forEach(detailReq -> {
            // 数量需大于0
            if (detailReq.getGoodsNum().compareTo(BigDecimal.ZERO) < 1) {
                return;
            }
            // 明细信息
            String modelId = detailReq.getGoodsModelId();
            GoodsModelVO model = modelMap.computeIfAbsent(modelId, k -> scmSaleBUtils.queryGoodsModelVO(k, buyerId, pricingDate));
            BuyOrderDetail detail;
            // 采购价 使用设置价
            BigDecimal buyPrice = detailReq.getBuyPrice();
            if (null == buyPrice) {
                buyPrice = model.getModelPrice();
                detailReq.setBuyPrice(buyPrice);
            }
            BigDecimal goodsNum = detailReq.getGoodsNum();
            if (existMap.containsKey(modelId)) {
                // 修改明细
                detail = existMap.get(modelId);
                detailMap.put(modelId, detail);
                existMap.remove(modelId);
                // 修改 数量/价格/备注
                detail.setGoodsNum(goodsNum);
                detail.setOrderGoodsNum(goodsNum);
                detail.setBuyPrice(buyPrice);
                detail.setRemarks(detailReq.getRemarks());
                detail.setStatus(BuyOrderStatusEnum.submit);
                detail.setSummaryFlag(DetailSummaryFlagEnum.wait);
            } else if (null == (detail = detailMap.get(modelId))) {
                detail = SalebTrans.initOrderDetail(detailReq, model);
                // 采购价
                detailMap.put(modelId, detail);
            } else {
                // 商品重复 数量相加,价格以后一个为准
                detail.setBuyPrice(buyPrice);
                detail.setGoodsNum(detail.getGoodsNum().add(goodsNum));
                detail.setOrderGoodsNum(detail.getGoodsNum());
            }
        });
    }

    private void checkModifyStatus(BuyOrder order) {
        if (order.getStatus() != BuyOrderStatusEnum.submit) {
            throw new ErrorDataException("订单状态有误: 需是已下单状态");
        }
        // 已支付的不能修改
        if (null != order.getPayStatus() && order.getPayStatus() != PayStatusEnum.wait) {
            throw new ErrorDataException("订单支付状态有误: 需是待支付状态");
        }
    }

    /**
     * 采购单取消
     *
     * @param buyOrderSn
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelBuyOrder(String buyOrderSn) {
        BuyOrder order = checkBuyOrder(buyOrderSn);
        checkModifyStatus(order);
        return cancelBuyOrder(order);
    }

    /**
     * 采购单取消
     *
     * @param order id、buyId
     * @return
     */
    private boolean cancelBuyOrder(BuyOrder order) {
        // 已有账单及发货单删除
        if (!scmSaleBUtils.deleteShipRecord(order.getBuyId(), OrderTypeEnum.buy)) {
            throw new ErrorDataException("已发货订单不可取消");
        }
        if (!scmSaleBUtils.deleteBillByOrder(order.getBuyId(), BillTypeEnum.order)) {
            throw new ErrorDataException("有已审核通过账单, 不可取消订单");
        }
        // 订单状态设置为取消
        BuyOrder cancel = new BuyOrder();
        cancel.setId(order.getId());
        cancel.setStatus(BuyOrderStatusEnum.cancel);
        buyOrderService.updateById(cancel);
        BuyOrderDetail detail = new BuyOrderDetail();
        detail.setStatus(BuyOrderStatusEnum.cancel);
        buyOrderDetailService.update(detail, Wrappers.<BuyOrderDetail>query().lambda()
                .eq(BuyOrderDetail::getBuyId, order.getBuyId())
        );
        return true;
    }

    /**
     * 修改采购单  (以前接口, 迁移后废弃)
     * 状态限制: 已下单
     *
     * @param modifyReq
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean modifyOrder(BuyOrderModifyReq modifyReq) {
        // 订单修改
        BuyOrder oldOrder = checkBuyOrder(modifyReq.getBuyId());
        if (oldOrder.getStatus() != BuyOrderStatusEnum.submit) {
            return false;
        }
        // 已支付的不能修改
        if (oldOrder.getPayStatus() != PayStatusEnum.wait) {
            return false;
        }
        List<BuyOrderDetail> existList = buyOrderDetailService.findListBySn(modifyReq.getBuyId());
        if (CollUtil.isEmpty(existList)) {
            throw new EmptyDataException("订单明细有误");
        }
        BuyOrder update = modifyReq.transTo();
        update.setId(oldOrder.getId());
        BigDecimal shipFee = oldOrder.getShipFee();
        if (null == shipFee) {
            shipFee = BigDecimal.ZERO;
            update.setShipFee(shipFee);
        }
        // 明细修改
        BigDecimal genPrice = modifyDetail(existList, modifyReq.getDetailList(), oldOrder);
        genPrice = genPrice.add(shipFee);
        update.setGenPrice(genPrice);
        buyOrderService.updateById(update);
        return true;
    }

    /**
     * (以前接口, 迁移后废弃)
     *
     * @param existList
     * @param detailList
     * @param buyOrder
     * @return
     */
    private BigDecimal modifyDetail(List<BuyOrderDetail> existList, List<BuyDetailModifyReq> detailList, BuyOrder buyOrder) {
        int size = existList.size() * 4 / 3 + 1;
        size = Math.max(size, 8);
        // 已存在明细
        Map<String, BuyOrderDetail> existMap = new HashMap<>(size);
        existList.forEach(detail -> {
            existMap.put(detail.getGoodsModelId(), detail);
        });
        // 修改后明细
        size = detailList.size() * 4 / 3 + 1;
        size = Math.max(size, 8);
        Map<String, BuyOrderDetail> detailMap = new HashMap<>(size);
        List<BuyOrderDetail> addList = new ArrayList<>(size);
        List<BuyOrderDetail> updateList = new ArrayList<>(size);
        Map<String, GoodsModelDTO> modelMap = new HashMap<>(size);


        detailList.forEach(detailReq -> {
            // 明细信息
            BuyOrderDetail detail;
            String modelId = detailReq.getGoodsModelId();
            BigDecimal goodsNum = detailReq.getGoodsNum();

            GoodsModelDTO model = modelMap.get(modelId);
            if (null == model) {
                model = scmSaleBUtils.queryGoodsModelById(modelId);
                modelMap.put(modelId, model);
            }
            // 采购价 使用商品市场价
            BigDecimal buyPrice = detailReq.getBuyPrice();
            if (null == buyPrice) {
                buyPrice = model.getModelPrice();
                detailReq.setBuyPrice(buyPrice);
            }
            if (existMap.containsKey(modelId)) {
                // 修改明细
                detail = existMap.get(modelId);
                detailMap.put(modelId, detail);
                existMap.remove(modelId);
                // 是否修改 数量/价格/备注
                if (!detailEquals(detail, detailReq)) {
                    detail.setGoodsNum(goodsNum);
                    detail.setOrderGoodsNum(goodsNum);
                    detail.setBuyPrice(buyPrice);
                    detail.setRemarks(detailReq.getRemarks());
                    updateList.add(detail);
                }
            } else if (detailMap.containsKey(modelId)) {
                // 商品重复 数量相加,价格以后一个为准
                detail = detailMap.get(modelId);
                detail.setBuyPrice(buyPrice);
                goodsNum = detail.getGoodsNum().add(goodsNum);
                detail.setGoodsNum(goodsNum);
                detail.setOrderGoodsNum(goodsNum);
            } else {
                // 新增明细
                detail = SalebTrans.initOrderDetail(detailReq, model, buyOrder);
                detailMap.put(modelId, detail);
                addList.add(detail);
            }
        });

        // 明细保存
        addList.forEach(buyOrderDetailService::save);
        updateList.forEach(detail -> {
            BuyOrderDetail update = new BuyOrderDetail();
            update.setId(detail.getId());
            update.setGoodsNum(detail.getGoodsNum());
            update.setOrderGoodsNum(detail.getOrderGoodsNum());
            update.setBuyPrice(detail.getBuyPrice());
            update.setRemarks(detail.getRemarks());
            buyOrderDetailService.updateById(update);
        });
        existMap.values().forEach(detail -> buyOrderDetailService.removeById(detail.getId()));

        return detailMap.values().stream()
                .map(detail -> detail.getGoodsNum().multiply(detail.getBuyPrice()))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * (以前接口, 迁移后废弃)
     *
     * @param detail
     * @param detailReq
     * @return
     */
    private boolean detailEquals(BuyOrderDetail detail, BuyDetailModifyReq detailReq) {
        if (detail.getGoodsNum().compareTo(detailReq.getGoodsNum()) != 0) {
            return false;
        }
        if (!StrUtil.equals(detail.getRemarks(), detailReq.getRemarks())) {
            return false;
        }
        return detail.getBuyPrice().compareTo(detailReq.getBuyPrice()) == 0;
    }

    /**
     * 订单结算状态修改
     *
     * @param buyOrderSn
     * @param status
     * @return
     */
    @Override
    public boolean updateOrderSettlement(String buyOrderSn, PayStatusEnum status) {
        BuyOrder order = buyOrderService.fetchBySn(buyOrderSn);
        if (order == null) {
            return false;
        }
        BuyOrder update = new BuyOrder();
        update.setId(order.getId());
        update.setPayStatus(status);
        return buyOrderService.updateById(update);
    }

    /**
     * 采购订单状态改变(不包括已取消)
     * 采购单状态：1.已下单2.待确认3.成交4.取消  5.待发货 6.待收货
     *
     * @param buyOrderSn
     * @param status     (修改后状态)
     * @return
     */
    @Override
    public boolean updateOrderStatus(String buyOrderSn, BuyOrderStatusEnum status) {
        BuyOrder order = checkBuyOrder(buyOrderSn);
        if (null == status || order.getStatus() == BuyOrderStatusEnum.cancel) {
            return false;
        }
        // 明细修改, 已取消状态不修改
        buyOrderDetailService.updateStatusByOrderSn(buyOrderSn, status);
        BuyOrder update = new BuyOrder();
        update.setId(order.getId());
        update.setStatus(status);
        buyOrderService.updateById(update);
        // 状态改为待发货时,需创建账单及发货单
        if (status == BuyOrderStatusEnum.delivery) {
            ScmGlobalThreadPool.getExecutor().execute(() -> {
                // 已创建账单的不修改
                ReceivableBill bill = scmSaleBUtils.fetchNormalBillByOrder(buyOrderSn);
                if (null == bill) {
                    scmSaleBUtils.createBill(buyOrderSn);
                }
                // 已创建发货单创建的不修改
                ShipRecord shipRecord = scmSaleBUtils.fetchShipRecord(buyOrderSn);
                if (null == shipRecord) {
                    scmSaleBUtils.createShipRecord(buyOrderSn);
                }
            });
        }
        return true;
    }

    /**
     * 按日期批量创建账单
     * 排除已取消订单
     *
     * @param req
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createBillBatch(CreateBillBathReq req) {
        List<BuyOrder> list = buyOrderService.list(Wrappers.<BuyOrder>query().lambda()
                .between(BuyOrder::getDeliveryTime, req.getStartDate(), req.getEndDate())
                .ne(BuyOrder::getStatus, BuyOrderStatusEnum.cancel)
        );
        if (CollUtil.isEmpty(list)) {
            return false;
        }
        Set<String> orderSnSet = list.stream()
                .map(BuyOrder::getBuyId)
                .filter(StrUtil::isNotEmpty)
                .collect(Collectors.toSet());
        scmSaleBUtils.createBillBatch(orderSnSet);
        // 发货单批量创建
        scmSaleBUtils.createShipRecordBatch(orderSnSet);
        return true;
    }

    /**
     * 账单重建(重新创建)
     * 排除已取消订单
     *
     * @param orderSn
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetBill(String orderSn) {
        BuyOrder order = checkBuyOrder(orderSn);
        if (order.getStatus() == BuyOrderStatusEnum.cancel) {
            throw new ErrorDataException("已取消订单, 不可创建账单");
        }
        scmSaleBUtils.createBill(orderSn);
        // 发货单创建(修改)
        scmSaleBUtils.createShipRecord(orderSn);
        return true;
    }

    /**
     * 根据订单编号(buyId)查询订单详情(带pmName,merchantName)
     *
     * @param orderSn
     * @return
     */
    @Override
    public OrderInfoDTO fetchOrderInfoWithExt(String orderSn) {
        BuyOrder order = checkBuyOrder(orderSn);
        List<BuyOrderDetail> detailList = buyOrderDetailService.findListBySn(orderSn);
        if (CollUtil.isEmpty(detailList)) {
            throw new ErrorDataException("订单明细有误");
        }
        // pmId、pmName、merchantId、merchantName信息
        Buyer buyer = checkBuyer(order.getBuyerId());
        // 平台商家
        Merchant pm = scmSaleBUtils.fetchPlatformMerchant();

        OrderInfoDTO result = SalebTrans.transToOrderInfo(order, detailList);
        result.setPmId(pm.getId());
        result.setPmName(pm.getMerchantName());
        result.setMerchantId(buyer.getMerchantId());
        result.setMerchantName(buyer.getMerchantName());
        return result;
    }

    @Override
    public IPage<BuyOrderVO> findPage(Page<BuyOrder> page, QueryBuyOrderReq req) {
        return findPage(page, req, false);
    }

    @Override
    public IPage<BuyOrderVO> findPage(Page<BuyOrder> page, QueryBuyOrderReq req, boolean needDetail) {
        // 按商家查询
        boolean flag = StrUtil.isNotEmpty(req.getMerchantId());
        List<String> buyerIds = null;
        if (flag) {
            buyerIds = buyerService.list(Wrappers.<Buyer>query().lambda()
                    .eq(Buyer::getMerchantId, req.getMerchantId())
            ).stream().map(Buyer::getId).collect(Collectors.toList());
            if (buyerIds.isEmpty()) {
                return new Page<>(page.getCurrent(), page.getSize());
            }
        }
        IPage<BuyOrder> orderPage = buyOrderService.page(page, Wrappers.query(req.transTo()).lambda()
                .in(null != req.getStatusSet() && !req.getStatusSet().isEmpty(), BuyOrder::getStatus, req.getStatusSet())
                .in(null != buyerIds, BuyOrder::getBuyerId, buyerIds)
                // 模糊查询
                .like(StrUtil.isNotEmpty(req.getBuyerName()), BuyOrder::getBuyerName, req.getBuyerName())
                .like(StrUtil.isNotEmpty(req.getContact()), BuyOrder::getContact, req.getContact())
                .like(StrUtil.isNotEmpty(req.getTelephone()), BuyOrder::getTelephone, req.getTelephone())
                .like(StrUtil.isNotEmpty(req.getAddress()), BuyOrder::getAddress, req.getAddress())
                .apply(null != req.getStartDate() && null != req.getEndDate(), "DATE(buy_time) between {0} and {1}", req.getStartDate(), req.getEndDate())
                .orderByDesc(BuyOrder::getCreateDate));

        IPage<BuyOrderVO> result = new Page<>(orderPage.getCurrent(), orderPage.getSize(), orderPage.getTotal());
        result.setRecords(orderPage.getRecords().stream()
                .map(item -> needDetail ? fetchInfo(item) : new BuyOrderVO(item)).collect(Collectors.toList()));
        return result;
    }

    @Override
    public BuyOrderVO fetchInfo(String buyOrderSn) {
        BuyOrder order = checkBuyOrder(buyOrderSn);
        return fetchInfo(order);
    }

    private BuyOrderVO fetchInfo(BuyOrder order) {
        List<BuyOrderDetail> detailList = buyOrderDetailService.findListBySn(order.getBuyId());
        if (CollUtil.isEmpty(detailList)) {
            throw new ErrorDataException("订单明细有误");
        }
        BuyOrderVO result = new BuyOrderVO(order);
        if (null == result.getGoodsNum()) {
            result.setGoodsNum(detailList.size());
        }
        result.setDetailList(detailList.stream()
                .filter(item-> item.getStatus() != BuyOrderStatusEnum.cancel)
                .map(BuyOrderDetailVO::new)
                .collect(Collectors.toList())
        );
        return result;
    }

    /**
     * 分页查询  buyOrder联查buyer 返回商家
     *
     * @param page
     * @param req
     * @return
     */
    @Override
    public IPage<OrderInfoDTO> findExtPage(Page page, QueryBuyOrderReq req) {
        BuyOrderSqlDTO query = req.transToSql();
        query.queryPage(page);
        return buyOrderService.findExtPage(query);
    }

    /**
     * 查询采购商常购买的商品规格id列表(销量最高的30个)
     *
     * @param buyerId
     * @return
     */
    @Override
    public List<String> queryOftenModelIds(String buyerId) {
        BuyOrderSqlDTO query = new BuyOrderSqlDTO();
        query.setBuyerId(buyerId);
        return buyOrderDetailService.queryOftenModelIds(query).stream()
                .map(BuyOrderDetail::getGoodsModelId)
                .collect(Collectors.toList());
    }


    private Buyer checkBuyer(String buyerId) {
        Buyer buyer = buyerService.getById(buyerId);
        if (null == buyer) {
            throw new ErrorDataException("订单中采购商有误");
        }
        return buyer;
    }

    private BuyOrder checkBuyOrder(String buyOrderSn) {
        BuyOrder order = buyOrderService.fetchBySn(buyOrderSn);
        if (null == order) {
            throw new ErrorDataException("订单有误");
        }
        return order;
    }
}
